在本系列文中,所有的程式碼以及測試都可以在 should-i-use-fp-ts 找到,今日的範例放在 src/day-04
。
今天要講述的主題是 declarative(宣告式) vs. imperative(命令式)
,這兩種敘述分別代表著兩種不同的程式風格,我們使用著名的斐波那契數字(LeetCode 509. Fibonacci Number)來展示,如果有讀者不熟悉的話可以到 LeetCode 頁面觀看這種數列的特性。
Imperative:
const fib = (n: number): number => {
if (n < 2) return n;
let [curr, prev1, prev2] = [0, 0, 1];
for (let index = 2; index <= n; index++) {
curr = prev1 + prev2;
prev1 = prev2;
prev2 = curr;
}
return curr;
};
Declarative:
const fib = (n: number): number => n < 2 ? n : fibDec(n - 1) + fibDec(n - 2);
雖然這兩個函式都能產出斐波那契數字,但他們呈現的方式卻天差地別,imperative
使用的方法就是大多數人學過的,用迴圈以及變數一行一行的精確的命令來推導出我們需要的結果。
而 declarative
則是宣告了我們需要的結果。
在 functional programming
的 style 中,我們會比較偏向使用 宣告式 而非 命令式,這樣不論是寫的人還是讀的人,都不需要花費時間來操作實作的細節。
另一個範例是 log
一個 array
中每個變數的值。
const arr = [1, 2, 3, 4, 5];
// most imperative
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// a little declarative
for (const v of arr) {
console.log(v);
}
// most declarative
arr.forEach(v => console.log(v));
從 for...
, for...of
到 forEach
,程式中的不必要的細節一層層的省略,讓程式碼中只包含核心作用的邏輯,從而提高程式的可讀性。